#include "PcmDecoder.hpp"
#include <cmath>

PcmDecoder::PcmDecoder() : sndFile(0) {

}
PcmDecoder::~PcmDecoder() {
    close();
}

bool PcmDecoder::load(const char* filename, bool silence) {
    sndFile=sf_open(filename, SFM_READ, &sndInfo);
    channels=(unsigned int)sndInfo.channels;
    frequency=(unsigned int)sndInfo.samplerate;
    samples=(unsigned int)sndInfo.sections;
    seekable=sndInfo.seekable!=0;
    return true;
}

void PcmDecoder::close() {
    sf_close(sndFile);
}
#include <iostream>
int PcmDecoder::decode(float* data, unsigned long frames) {
    unsigned long toDecode=frames;
    int ret=0;
    if(frequency!=desiredFrequency) {
        SRC_DATA sd;
        float ratio=frequency/desiredFrequency;
        sd.data_out=data;
        sd.output_frames=frames;
        sd.src_ratio=frequency/desiredFrequency;
        std::cout << "Ratio: " <<ratio << " - " <<frequency<<"/"<<desiredFrequency <<std::endl;
        toDecode=ceil(frames*ratio);
        float *tmp=(float*)malloc(sizeof(float)*toDecode);
        ret=sf_readf_float(sndFile, tmp, toDecode);
        sd.data_in=tmp;
        sd.input_frames=toDecode;
        src_simple(&sd, SRC_SINC_BEST_QUALITY, channels);
        free(tmp);
    }
    else ret=sf_readf_float(sndFile, data, toDecode);
    return ret;
}

bool PcmDecoder::seek(unsigned int frame) {
    if(!seekable) return false;
    int64_t p=sf_seek(sndFile, frame, SEEK_SET);
    if(p==-1) return false;
    position=(unsigned int)p;
    return true;
}
